package com.fingard.dsp.bank.directbank.zjrc01;

import com.fingard.constant.Format;
import com.fingard.diagnostics.LogHelper;
import com.fingard.dsp.bank.dbobj.receipt.ReceiptData;
import com.fingard.dsp.bank.dbobj.receipt.ReceiptDataHelper;
import com.fingard.dsp.bank.dbobj.updownfile.DownFileHelper;
import com.fingard.dsp.bank.dbobj.updownfile.DownFileRecord;
import com.fingard.dsp.bank.directConfig.ReceiptProConfig;
import com.fingard.dsp.bank.directConfig.TaskTimerSet;
import com.fingard.dsp.bank.directbank.bankInterface.IScheduleTask;
import com.fingard.dsp.bank.sepro.ReceiptPro;
import com.fingard.dsp.task.DelayCounter;
import com.fingard.dsp.task.command.SyncReceipt;
import com.fingard.generalobj.ExecResponse;
import com.fingard.io.FileHelper;
import com.fingard.text.StringHelper;
import com.fingard.util.DateHelper;
import com.itextpdf.text.pdf.BaseFont;
import com.fingard.FGBiz;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.xhtmlrenderer.pdf.ITextFontResolver;
import org.xhtmlrenderer.pdf.ITextRenderer;

import java.io.*;
import java.math.BigDecimal;
import java.sql.SQLException;
import java.text.ParseException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;


public class ZJRC01ScheduleTask extends ZJRC01Base implements IScheduleTask {
    private String logCode = "ZJRC01"+File.separator+"TaskReceiptPro";
    private TaskTimerSet timer;
    private ReceiptProConfig proConfig;
    private static DelayCounter delayCounter = new DelayCounter(45, 2);//最大延时45分钟，按平方计算，即4次=4*4=16分钟
    public static void resetDelayCounter(){
        delayCounter.resetZeroCount();
    }

    @Override
    public void execTask(TaskTimerSet timerSet) {
        try{
            if (timerSet.taskNameList.toLowerCase().contains("downreceiptpro")) {
                timer = timerSet;
                proConfig = ReceiptPro.getReceiptProConfig();
                downReceipt();
            }
        }catch (Exception e){
            FGBiz.logTrace.exception(logCode, e);
        }
    }

    //电子回单html转pdf文件
    private void downReceipt(){
        int beginMonthCount = timer.getParamAsInt("beginMonthCount", -1);
        int endMonthCount = timer.getParamAsInt("endMonthCount", 0);
        if(beginMonthCount>endMonthCount){
            int chg = beginMonthCount;
            beginMonthCount = endMonthCount;
            endMonthCount = chg;
        }
        int needDownCount=0;//需要处理的文件数
        int succDownCount=0;//成功处理的回单数
        Date nowDay = new Date();
        for(int mthCount=beginMonthCount; mthCount<=endMonthCount; mthCount++) {
            //按日循环，取DOWNFILE表中的记录
            Date eachDay = DateHelper.addMonths(nowDay, mthCount);
            DownFileHelper dfHelper = null;
            try {
                dfHelper = new DownFileHelper(bankFront.tenant, eachDay);
                //获取该前置机该分区所有待下载的文件
                HashMap<Long, Integer> uridList = dfHelper.getAllNeedDownList(bankFront.bankCode, bankFront.code);
                if(uridList != null && uridList.size() > 0) {
                    needDownCount += uridList.size();
                    //遍历每个需要下载的文件
                    for(Map.Entry<Long,Integer> entry:uridList.entrySet()){
                        long urid = entry.getKey();
                        //逐个执行
                        //取得要下载的文件记录
                        DownFileRecord fileRdForUpd = dfHelper.loadFromDbByUrid(urid);
                        if(fileRdForUpd!=null){
                            fileRdForUpd.downTime = new Date();
                            ExecResponse resp = downEachRdByFileRecord(fileRdForUpd);
                            if(resp.isSucceed){
                                succDownCount++;
                                fileRdForUpd.downState = "2";
                                fileRdForUpd.downInfo = resp.getResultAsString();
                            }else{
                                fileRdForUpd.downState = "3";
                                fileRdForUpd.downInfo = resp.logMsg;
                                FGBiz.logTrace.error(logCode,"urid为"+urid+"的记录，"+resp.logMsg);
                            }
                            int rowsAff = dfHelper.updateDownState(fileRdForUpd);
                            if(rowsAff<1){
                                FGBiz.logTrace.info(logCode,"urid:"+urid+"的记录，更新行数："+rowsAff);
                            }
                        }else{
                            FGBiz.logTrace.error(logCode,"urid:"+urid+"的记录，已被移除");
                        }
                    }
                }else{
                    FGBiz.logTrace.info(logCode, "取"+Format.Date6YearMonth.format(eachDay)+"线路"+bankFront.bankCode+"前置机"+bankFront.code+"的待下载文件记录为空");
                }
            }catch(Exception ex){
                FGBiz.logTrace.exception(logCode, ex);
            }finally{
                if(dfHelper!=null){
                    dfHelper.close();
                }
            }
        }
        FGBiz.logTrace.info(logCode, "本次需下载"+needDownCount+"个，下载成功"+succDownCount+"个");
        if(succDownCount == 0){
            delayCounter.increaseZeroCount();
            FGBiz.logTrace.info(logCode, "成功个数为0，下次执行将增加延时"+delayCounter.getDelayMinutes()+"分钟");
        }else{
            delayCounter.resetZeroCount();
            SyncReceipt.resetDelayCounter();//同步任务重新计数延时
        }
    }

    /**根据URID，进行下载及处理，返回保存成功条数
     * @throws ParseException
     * @throws SQLException
     * @throws IllegalAccessException
     * @throws IllegalArgumentException
     * @throws IOException */
    private ExecResponse downEachRdByFileRecord(DownFileRecord pFileRd) throws IllegalArgumentException{
        String localSaveSir=StringHelper.trimEndFileSp(proConfig.getValueAsString("localSaveDir"));//本地pdf回单保存父路径
        ExecResponse retResp = new ExecResponse();//处理结果类
        ReceiptDataHelper receiptHelper = null;//回单数据保存类，分区分表
        try{
            File localReceiptFile=new File(pFileRd.filePath);
            if(localReceiptFile.exists()){
                //获取html名称，解析数据
                String htmlName=localReceiptFile.getName();
                String[] infoArr=htmlName.replace(".html","").split("_");//柜员流水号_子流水号_时间_回单类型_借贷标识(1入账2出账)_币种
                //获取html数据，进行处理
                String htmlContext=FileHelper.readFileText(localReceiptFile.getPath(),getCharset());
                Document receiptDoc = (Document) Jsoup.parse(htmlContext);
                Element receiptNoTable = receiptDoc.select("#tradeDetailTab").last();//获取
                if(receiptNoTable!=null){
                    String res=receiptNoTable.toString();
                    res=res.replaceAll("\n","").replaceAll(" ","")
                            .replaceAll("<span>","").replaceAll("</span>","");//回单数据串
                    //html转pdf
                    OutputStream os=null;
                    try{
                        String pdfSavePath=localSaveSir+File.separator+infoArr[0]+"_"+infoArr[1]+"_"+infoArr[2]+".pdf";
                        os = new FileOutputStream(pdfSavePath);
                        ITextRenderer renderer = new ITextRenderer();
                        ITextFontResolver fontResolver = renderer.getFontResolver();
                        fontResolver.addFont(fontFamily, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
                        renderer.setDocument(localReceiptFile);
                        renderer.getSharedContext().setBaseURL(getImgUrlByKey(res,"电子回单专用章"));
                        renderer.layout();
                        renderer.createPDF( os );
                        //校验pdf文件
                        boolean result=isCheckPdf(pdfSavePath);
                        if(result){
                            //数据入库
                            String uniqueSeqId=infoArr[0]+infoArr[1]+infoArr[2];
                            ReceiptData eachData = new ReceiptData();
                            /**回单唯一标识（在银行端的唯一标识（该账号的唯一），如招行的打印实例号）*/
                            eachData.istNbr=uniqueSeqId;
                            /**回单关联号（回单编号）*/
                            eachData.receiptNo=uniqueSeqId;
                            /**业务参考号*/
                            eachData.busRef=uniqueSeqId;
                            /**银行流水号*/
                            eachData.bnkSeqNo=uniqueSeqId;
                            /**本方账号*/
                            eachData.ownAct=pFileRd.ownAct;
                            /**银行代码，如工行102*/
                            eachData.bank=banks;
                            /**线路代码（来源渠道），如工行直联ICBC02*/
                            eachData.srcSys=this.bankFront.bankCode;
                            /**日期*/
                            eachData.busDate=pFileRd.busDate;
                            /**对方账号*/
                            eachData.oppActNum=getValueByKey(res,"收款人账");
                            /**对方户名*/
                            eachData.oppActName=getValueByKey(res,"收款人户");
                            /**交易方向*/
                            String cdFlag=infoArr[4];
                            if("1".equals(cdFlag)){
                                eachData.moneyWay="2";
                            }else if("2".equals(cdFlag)){
                                eachData.moneyWay="1";
                            }
                            /**币种*/
                            eachData.cur=convertCurToATS(infoArr[5]);
                            try {
                                /**金额*/
                                String amount=getValueByKey(res,"金额");
                                if(amount.startsWith(".")){
                                    amount="0"+amount;
                                }else if(StringHelper.isNullOrEmpty(amount)){
                                    amount="0.00";
                                }
                                eachData.amount=new BigDecimal(amount);
                            } catch (Exception ex) {
                                retResp.logMsg = LogHelper.getStackTrace(ex);
                                FGBiz.logTrace.exception(logCode, ex,"金额异常，异常文件为："+pFileRd.filePath);
                                return retResp;
                            }
                            /**用途*/
                            eachData.purpose=getValueByKey(res,"附言");
                            /**回单文件--本地文件相对路径*/
                            eachData.localFile=StringHelper.getRelativePath(pdfSavePath, localSaveSir);
                            /**源文件路径*/
                            eachData.srcFile=pdfSavePath;
                            /**回单文件类型*/
                            eachData.fileType="1";
                            /**下载状态：指从银行下载该回单文件的状态，1未下载；2已下载；3下载失败；4下载中*/
                            eachData.downState="2";
                            /**下载时间*/
                            eachData.downTime=new Date();
                            /**下载信息，如果失败则为失败原因*/
                            eachData.downInfo="下载成功";
                            /**上传状态：指文件从银行端下载完成后，上传至ftp或ats或oss或客制化文件服务的状态，1未上传；2已上传；3上传失败；4上传中*/
                            eachData.upState="1";
                            /**推送状态：指文件上传完成后，回单数据推送至ats或客制化平台的状态，1未推送；2已推送；3推送失败；4推送中*/
                            eachData.pushState="1";
                            /**创建时间*/
                            eachData.createdOn=new Date();
                            /**最后修改时间*/
                            eachData.lastModifiedOn=new Date();
                            /**版本号*/
                            eachData.rowVersion=1;
                            receiptHelper = new ReceiptDataHelper(reqHeader.tenant, eachData.getBusDate());
                            //回单数据记录入库
                            int inRe = receiptHelper.insertIfNotExist(eachData);
                            if(inRe>0){
                                retResp.isSucceed=true;
                                retResp.rdCount++;
                            }else{
                                FGBiz.logTrace.info(logCode,eachData.receiptNo+"写入数据库，影响行数："+inRe);
                            }
                        }else {
                            FGBiz.logTrace.error(logCode,"pdf转换失败，此"+localReceiptFile+"文件存在格式异常，请重新查询并检查");
                        }
                    }catch (Exception ex){
                        retResp.logMsg = LogHelper.getStackTrace(ex);
                        FGBiz.logTrace.exception(logCode, ex,"异常数据为："+pFileRd.filePath+"="+htmlContext);
                    }finally {
                        try {
                            if(os!=null){
                                os.close();
                            }
                        }catch (Exception e){
                            WriteBankLogLn(e);
                        }
                    }
                }
            }else {
                FGBiz.logTrace.error(logCode,"本地已将回单文件"+localReceiptFile.getPath()+"移除,请重新查询");
            }
        }catch(Exception ex){
            retResp.logMsg = LogHelper.getStackTrace(ex);
            FGBiz.logTrace.exception(logCode, ex,"异常的文件路径："+pFileRd.filePath);
        }finally{
            if(receiptHelper!=null){
                receiptHelper.close();
            }
        }
        return retResp;
    }
}
